/*
 * @Author: your name
 * @Date: 2021-05-24 15:25:57
 * @LastEditTime: 2021-05-27 16:33:56
 * @LastEditors: Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: \lottery\index.ts
 */
interface resultType {
  name: string,
  type: 0|1|2,
  word: string,
  message?: string
}
interface location {
  x: number,
  y: number,
  id?: string
}
interface card {
  width: number,
  height: number
}
type times = 'first' | 'sec'

enum timeStorage {
  first = '_result_gc_first',
  sec = '_result_gc_second'
}
enum timeCount {
  first = 10,
  sec = 15
}

class Lottery {
  private GIFTLIST:Array<resultType> = [
    {
      name: '1',
      type: 1,
      word: 'hahaha',
      message: 'nihao'
    },
    {
      name: '1',
      type: 1,
      word: 'hahaha',
      message: 'nihao'
    },
    {
      name: '1',
      type: 1,
      word: 'hahaha',
      message: 'nihao'
    },
    {
      name: '1',
      type: 1,
      word: 'hahaha',
      message: 'nihao'
    },
    {
      name: '1',
      type: 1,
      word: 'hahaha',
      message: 'nihao'
    },
    {
      name: '1',
      type: 1,
      word: 'hahaha',
      message: 'nihao'
    },
    {
      name: '1',
      type: 1,
      word: 'hahaha',
      message: 'nihao'
    },
    {
      name: '1',
      type: 1,
      word: 'hahaha',
      message: 'nihao'
    },
    {
      name: '1',
      type: 1,
      word: 'hahaha',
      message: 'nihao'
    },
    {
      name: '1',
      type: 1,
      word: 'hahaha',
      message: 'nihao'
    },
    {
      name: '1',
      type: 1,
      word: 'hahaha',
      message: 'nihao'
    },
    {
      name: '1',
      type: 1,
      word: 'hahaha',
      message: 'nihao'
    },
    {
      name: '1',
      type: 1,
      word: 'hahaha',
      message: 'nihao'
    },
    {
      name: '1',
      type: 1,
      word: 'hahaha',
      message: 'nihao'
    },{
      name: '1',
      type: 1,
      word: 'hahaha',
      message: 'nihao'
    },
    {
      name: '1',
      type: 1,
      word: 'hahaha',
      message: 'nihao'
    },
    {
      name: '1',
      type: 1,
      word: 'hahaha',
      message: 'nihao'
    },
    {
      name: '1',
      type: 1,
      word: 'hahaha',
      message: 'nihao'
    },
    {
      name: '1',
      type: 1,
      word: 'hahaha',
      message: 'nihao'
    },
    {
      name: '1',
      type: 1,
      word: 'hahaha',
      message: 'nihao'
    },{
      name: '1',
      type: 1,
      word: 'hahaha',
      message: 'nihao'
    },{
      name: '1',
      type: 1,
      word: 'hahaha',
      message: 'nihao'
    },{
      name: '1',
      type: 1,
      word: 'hahaha',
      message: 'nihao'
    },{
      name: '1',
      type: 1,
      word: 'hahaha',
      message: 'nihao'
    },{
      name: '1',
      type: 1,
      word: 'hahaha',
      message: 'nihao'
    },{
      name: '1',
      type: 1,
      word: 'hahaha',
      message: 'nihao'
    },{
      name: '1',
      type: 1,
      word: 'hahaha',
      message: 'nihao'
    },{
      name: '1',
      type: 1,
      word: 'hahaha',
      message: 'nihao'
    },{
      name: '1',
      type: 1,
      word: 'hahaha',
      message: 'nihao'
    },{
      name: '1',
      type: 1,
      word: 'hahaha',
      message: 'nihao'
    }
  ]
  private typeMap:Array<string> = ['无', '立即', '当天', '预支']
  private CARD_COUNT:number = this.GIFTLIST.length
  private GET_COUNT:number = 10
  private CARD:card = {
    width: 75,
    height: 100,
  }

  private BOX:card = {
    width: 300,
    height: 200
  }

  private BOX_LOCATION:location

  private card_location_list:Array<location>
  private timerList = {}
  private timerFastList = {}
  
  public result:Array<resultType> = []
  private idMapResult: object = {}
  private times:times
  private timeStorageName:timeStorage

  constructor(times:times) {
    this.times = times
    this.timeStorageName = timeStorage[this.times]
    this.GET_COUNT = timeCount[this.times]
    this.GIFTLIST = []
    for (let i = 0; i < 30; i++) {
      this.GIFTLIST.push({
        name: '名字' + i,
        type: 1,
        word: '显示点什么吧，比如：' + i * 2342,
        message: '可有可无'
      })
      
    }
  }

  async initCard() {
    const location = this.randomLocation()
    this.card_location_list = location
    for (let i = 0; i < location.length; i++) {
      const element = location[i];
      this.drawCard(element.x, element.y, element.id)
    }
    this.BOX_LOCATION = this._getBoxLocation()
    console.log(this.BOX_LOCATION.y)
    await this._delay(() =>{
      for (let i = 0; i < location.length; i++) {
        const element = location[i];
        this.move(element, 10)
      }
      setTimeout(() => {this.addEventOnBox()}, 2200)
    },800)
  }
  
  randomLocation():Array<location> {
    let location:Array<location> = []
    const count:number = this.GET_COUNT
    let width = document.body.offsetWidth - this.CARD.width
    let height = document.body.offsetHeight - 250 - this.CARD.height
    const randomWidthList = this.randomPush(width, count)
    const randomHeightList = this.randomPush(height, count)
    for (let i = 0; i < count; i++) {
      location.push({
        x: randomWidthList[i],
        y: randomHeightList[i],
        id: Date.now().toString() + i
      })
    }
    return location
  }
  
   drawCard(left: number, top: number, id: string = Date.now().toString()) {
     const div = document.createElement('div')
     div.setAttribute('style', `width:${this.CARD.width.toString() + 'px'};height:${this.CARD.height.toString() + 'px'};left: ${left + 'px'};top:${top + 'px'}`)
     div.setAttribute('class', 'card')
     div.setAttribute('id', 'card' + id)
     document.getElementById('card').appendChild(div)
  }

  private addEventOnBox() {
    const box = document.getElementById('box')
    const btn = document.createElement('button')
    btn.innerHTML = '点击抽取'
    btn.setAttribute('id', 'btn-lottery')
    btn.setAttribute('class', 'btn')
    btn.addEventListener('click', this.btnClickHandle.bind(this))
    box.appendChild(btn)
  }

  private addBoxEvent(id: string) {
    const dom = document.getElementById('card' + id)
    const show = document.getElementById('shows')
    dom.addEventListener('click', () => {
      // dom.style.transform = 'rotate(360deg)'
      const isShow = show.style.display !== 'none'
      let top = dom.style.top
      console.log(show.style.display)
      if (isShow) return
      show.style.display = 'block'
      dom.style.transition = 'width 1s, height 1s, top 1s, color 2s'
      dom.style.width = '300px'
      dom.style.height = '400px'
      dom.style.top = '150px'
      dom.style.zIndex = '999'
      dom.style.backgroundColor = '#fff'
      this.rotateCard(dom, id)
      show.addEventListener('click', () => {
        show.style.display = 'none'
        dom.style.height = '100px'
        dom.style.width = '75px'
        dom.style.top = top
        dom.style.zIndex = '1'
        dom.style.color = '#fff'
        dom.style.fontSize = '12px'
        dom.style.backgroundColor = '#000'
      })
    })
  }

  private drawCardContent(id) {
    const res = this.idMapResult[id] || {}
    if (Object.keys(res).length === 0) return
    const container = document.getElementById('card' + id)
    const el = `
      <div class="opcity">
        <div>${res.name}</div>
        <div>${res.type}</div>
        <div>${res.word}</div>
        <div>${res.message}</div>
      </div>
    `
    container.innerHTML = el
  }

  private rotateCard(dom:HTMLElement, id: string) {
    let i= 0
    this.timerList['rotate' + id] = setInterval(() => {
      if (i >= 720) {
        clearInterval(this.timerList['rotate' + id])
        this.drawCardContent(id)
      }
      dom.style.transform = 'rotateY('+ i +'deg)'
      i+=16
    }, 15)
  }

  private getResult() {
    const res = localStorage.getItem(this.timeStorageName)
    const rest = localStorage.getItem('_rest_gc_list')
    if (res) {
      this.result = JSON.parse(res)
      return
    }
    let gifts = []
    if (rest) gifts = JSON.parse(rest)
    else gifts = this.GIFTLIST
    for (let i = 0; i < this.GET_COUNT; i++) {
      const values = this.random(gifts.length)
      console.log(values)
      this.result.push(gifts[values])
      gifts.splice(values, 1)
    }
    localStorage.setItem(this.timeStorageName, JSON.stringify(this.result))
    !rest && localStorage.setItem('_rest_gc_list', JSON.stringify(gifts))
  }

  private btnClickHandle(e: Event) {
    document.getElementById('card').innerHTML = ''
    this.getResult()
    for (let i = 0; i < this.GET_COUNT; i++) {
      const location = this.scaleContainerLocation(i)
      this.drawCard(this.BOX_LOCATION.x, this.BOX_LOCATION.y, location.id)
      this.move({...this.BOX_LOCATION, id: location.id}, 2, location)
      this.addBoxEvent(location.id)
      this.idMapResult[location.id] = this.result[i]
    }
  }

  private move(card: location, time: number, target: location = this.BOX_LOCATION) {
    // 匀速
    // const disX = (card.x - this.BOX_LOCATION.x) / time / 10
    // const disY = (card.y - this.BOX_LOCATION.y) / time / 10
    // 变速
    let i = 0, j = 0, count = time * 10, slow = Math.floor(count / 2), fast = count - slow
    const speedX = Math.ceil(card.x - target.x)
    const speedY = Math.ceil(card.y - target.y)
    const slowDisX = Math.ceil(speedX * 0.35)
    const slowStepX = slowDisX / slow
    const fastDisX = speedX - slowDisX
    const fastStepX = fastDisX / fast
    const slowDisY = Math.ceil(speedY * 0.35)
    const slowStepY = slowDisY / slow
    const fastDisY = speedY - slowDisY
    const fastStepY = fastDisY / fast
    const cd = document.getElementById('card' + card.id)
    this.timerList[card.id] = setInterval(() => {
      if (slow < 0) {
        clearInterval(this.timerList[card.id])
        const lenX = card.x - slowDisX
        const lenY = card.y - slowDisY
        // console.log(lenX, lenY)
        this.timerFastList[card.id] = setInterval(() => {
          if (fast < 0) {
            clearInterval(this.timerFastList[card.id])
            // this.addEventOnBox()
          }
          this.moveFunc(cd, lenX - j * fastStepX, lenY - j * fastStepY)
          j ++
          fast --
        }, 20)
      }
      // if (count < 0) clearInterval(this.timerList[card.id])
      this.moveFunc(cd, card.x - slowStepX * i, card.y - slowStepY * i)
      slow --
      i ++
      // this.moveFunc(cd, card.x - disX * i, card.y - disY * i)
      // count --
      // i ++
    }, 20)
  }

  private moveFunc(node, x, y) {
    node.style.left = x + 'px'
    node.style.top = y + 'px'
  }

  private _getBoxLocation():location {
    const box = document.getElementById('box')
    return {
      x: box.offsetLeft + (this.BOX.width / 2),
      y: box.offsetTop + (this.BOX.height / 4)
    }
  }

  private _getMaxCount():number {
    return Math.floor((document.body.clientWidth - 400) / (this.CARD.width + 20))
  }

  private scaleContainerLocation(num: number):location {
    let left = 200 + (this.CARD.width + 20) * num
    let top = 100 + Math.floor(num / this._getMaxCount()) * (this.CARD.height + 20)
    return {
      x: left,
      y: top,
      id: (Date.now() + num).toString()
    }
  }
  
  
  // const storage:string = localStorage.getItem('gc_storage_cardlist')
  // let res:Array<resultType>
  // if (storage) {
  //   res = JSON.parse(storage)
  // } else {
  
  // }
  private randomPush(max:number, count:number = 1):Array<number>|number {
    let arr:Array<number> = []
    if (count > max) count = max
    while (count > 0) {
      let val = this.random(max)
      if (arr.indexOf(val) === -1) {
        arr.push(val)
        count --
      }
    }
    if (count === 1) return arr[0]
    return arr
  }
  
  private random(max:number):number {
    return Math.floor(Math.random() * max) 
  }

  private _delay(fn:Function,time: number) {
    setTimeout(() => {
      fn()
    }, time)
  }
}